import datetime
import pytz

import coin.exchange.base.kr_rest.public_client_base as pubcb
import coin.exchange.huobi_futures_swap.kr_rest.native_public_client as npubc
from coin.exchange.huobi_futures.kr_rest.futures_product import HuobiFuturesProduct
from coin.proto.coin_market_query_pb2 import (
    ProductKlineElement,
    ProductKline,
)


class HuobiSwapFuturesFeedParser(object):
  @staticmethod
  def parse_native_kline(update_msg, product, kline_period, start_time, end_time):
    klines = update_msg['data']
    kline_group = []
    for kline in klines:
      kline_timestamp = kline['id']
      if kline_timestamp >= start_time.timestamp() and \
         kline_timestamp < end_time.timestamp():
        product_kline = ProductKlineElement(kline_timestamp=int(kline['id'] * 1e+9),
                                            open=float(kline['open']),
                                            high=float(kline['high']),
                                            low=float(kline['low']),
                                            close=float(kline['close']),
                                            volume=float(kline['vol']) / 2,
                                            turnover=float(kline['amount']) / 2)
        kline_group.append(product_kline)
    assert len(kline_group) > 0
    return ProductKline(
        symbol=product.symbol,
        native_symbol=product.native_symbol,
        exchange='Huobi',
        market_type='Futures',
        kline_period=kline_period,
        klines=kline_group,
    )

  @staticmethod
  def parse_usdt_swap_native_kline(
      update_msg, product, kline_period, start_time, end_time):
    klines = update_msg['data']
    kline_group = []
    for kline in klines:
      kline_timestamp = kline['id']
      if kline_timestamp >= start_time.timestamp() and \
         kline_timestamp < end_time.timestamp():
        product_kline = ProductKlineElement(kline_timestamp=int(kline['id'] * 1e+9),
                                            open=float(kline['open']),
                                            high=float(kline['high']),
                                            low=float(kline['low']),
                                            close=float(kline['close']),
                                            volume=float(kline['vol']) / 2,
                                            turnover=float(kline['trade_turnover']) / 2)
        kline_group.append(product_kline)
    assert len(kline_group) > 0
    return ProductKline(
        symbol=product.symbol,
        native_symbol=product.native_symbol,
        exchange='Huobi',
        market_type='Futures',
        kline_period=kline_period,
        klines=kline_group,
    )


class HuobiSwapFuturesPublicClient(pubcb.PublicClientBase):
  def __init__(self, timeout=1):
    self.npubc = npubc.HuobiSwapNativePublicClient(timeout=timeout)

  def query_history_kline_impl(self, product, kline_period, start_time, end_time):
    if product.quote.currency == 'USDT':
      update = self.npubc.get_usdt_swap_history_kline(
          product.native_symbol, kline_period, start_time, end_time)
      update.msg = HuobiSwapFuturesFeedParser.parse_usdt_swap_native_kline(
          update.msg, product, kline_period, start_time, end_time)
    elif product.quote.currency == 'USD':
      update = self.npubc.get_history_kline(
          product.native_symbol, kline_period, start_time, end_time)
      update.msg = HuobiSwapFuturesFeedParser.parse_native_kline(
          update.msg, product, kline_period, start_time, end_time)
    else:
      raise ValueError(product)
    return update

  def query_level_book_impl(self, product):
    raise NotImplementedError()


if __name__ == "__main__":
  client = HuobiSwapFuturesPublicClient()
  start_time = datetime.datetime(2020, 11, 15).replace(tzinfo=pytz.UTC)
  end_time = datetime.datetime(2020, 11, 15, 23, 59, 59).replace(tzinfo=pytz.UTC)
  print(client.query_history_kline(
      HuobiFuturesProduct.FromStr('BTC-USDT.PERPETUAL'), '60min', start_time, end_time))
  print(client.query_history_kline(
      HuobiFuturesProduct.FromStr('BTC-USD.PERPETUAL'), '60min', start_time, end_time))
